visutils uses R basic graphics to visualize visium data in vareity of ways. The Main plotting function is plotVisium.
#devtools::install_github("iaaka/visutils")
library(visutils)
library(Seurat)
## Warning: package 'Seurat' was built under R version 4.0.5
## Attaching SeuratObject
## Attaching sp
loadVisiumFrom10x("https://cf.10xgenomics.com/samples/spatial-exp/1.3.0","Visium_Mouse_Olfactory_Bulb",outdir="data")
mob = Load10X_Spatial('data/Visium_Mouse_Olfactory_Bulb/')
Lets loa clustering information from just downloaded spaceranger output
cl = read.csv('data/Visium_Mouse_Olfactory_Bulb/analysis/clustering/graphclust/clusters.csv',row.names = 1)
mob$clusters = as.character(cl[colnames(mob),1])
table(mob$clusters,useNA = 'always')
##
## 1 2 3 4 5 6 7 <NA>
## 262 185 172 161 153 131 121 0
plotVisium(mob,z = mob$clusters)
## Quantitative variable
plotVisium(mob,z = mob$nCount_Spatial)
Lets explore the parameters
par(mar=c(0,0,1,6),bty='n')
plotVisium(mob,z = mob$nCount_Spatial,
zfun = log1p, # log scale
z2col = function(x)num2col(x,col = c('black','gray','orange','red')), # change colors
cex = scaleTo(log1p(mob$nCount_Spatial)), # spot size it proportional to log1p of coverage
legend.args = list(title='UMIs') # set legend title
)
Visualization of visium on top of H&E image internally performed by plotVisiumImg, plotVisium passes arguments to it. Check manual of plotVisiumImg to get more control over plotting
par(mar=c(0,0,1,6),bty='n')
plotVisium(mob,z = mob$nCount_Spatial,
zfun = log1p, # log scale
z2col = function(x)num2col(x,col = c('black','gray','orange','red')), # change colors
cex = scaleTo(log1p(mob$nCount_Spatial)), # spot size it proportional to log1p of coverage
zlim= c(500,2e4), # specify limits of value shown by color, all values outside of the range will be trimmed to the range
legend.args = list(title='UMIs'), # set legend title
he.grayscale = TRUE, # show H&E image in grayscale
img.alpha = 0.5, # make H&E image semi-transparent
he.img.width = 400 # reduce resolution of H&E image (helps to reduce file size when saving to pdf)
)
## Loading required package: EBImage
If you need H&E only
par(mar=c(0,0,1,6),bty='n')
plotVisium(mob,cex=0)
There are two ways to show multiple variable (for example genes): pie plots or mean colors. Lets first find genes to be shown.
mob = NormalizeData(mob)
Idents(mob) = "clusters"
markers = FindAllMarkers(mob)
## Calculating cluster 1
## Calculating cluster 7
## Calculating cluster 4
## Calculating cluster 5
## Calculating cluster 3
## Calculating cluster 6
## Calculating cluster 2
markers[1:5,]
## p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene
## Gm42418 5.235306e-114 2.146382 0.981 1.000 1.690219e-109 1 Gm42418
## Ptgds 8.944307e-113 3.784747 0.996 0.987 2.887670e-108 1 Ptgds
## Fabp7 2.799721e-93 2.249930 0.966 0.993 9.038901e-89 1 Fabp7
## Apod 1.207440e-91 2.644788 0.947 0.922 3.898220e-87 1 Apod
## Apoe 3.684006e-90 1.322135 0.996 1.000 1.189381e-85 1 Apoe
Lets select one genes per cluster
m = markers[markers$pct.1-markers$pct.2 > 0.3,]
m = do.call(rbind,lapply(split(m,m$cluster),function(x)x[order(x$avg_log2FC,decreasing = TRUE)[1],]))
m = m[order(as.character(m$cluster)),]
m
## p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene
## 1 2.528823e-54 1.8989167 0.645 0.264 8.164305e-50 1 Omp
## 2 4.888868e-31 0.8058507 0.595 0.239 1.578371e-26 2 Vip
## 3 1.594457e-79 1.5089431 0.953 0.288 5.147706e-75 3 Ly6g6e
## 4 3.374414e-53 1.0385090 1.000 0.660 1.089429e-48 4 Ptk2b
## 5 2.698230e-77 1.6047715 1.000 0.609 8.711235e-73 5 Penk
## 6 4.930226e-34 0.9884102 0.870 0.485 1.591723e-29 6 Lcat
## 7 2.710175e-62 1.3021307 0.950 0.349 8.749801e-58 7 Shisa3
par(mfrow=c(2,4),mar=c(0,0,1,0),bty='n')
for(gid in m$gene)
plotVisium(mob,mob@assays$Spatial@data[gid,],main=gid,plot.legend = FALSE)
# select genes to be plotted, matrix should be cell-by-gene, so lets transpose it
exps = t(as.matrix(mob@assays$Spatial@data[m$gene,]))
cols = RColorBrewer::brewer.pal(nrow(m),'Set1')
par(mfrow=c(1,2),mar=c(0,0,1,10),bty='n')
plotVisiumMultyColours(mob,exps,
cols = cols,
zfun = function(x)x^2, # kernel to transform gene expression. Higher powers will give more sharp figure (each spot will be dominated by single cell type)
mode = 'mean', # colors are averaged not overlayed (in this mode gene order makes no difference)
legend.ncol = 2, # show legend in two columns
he.grayscale = TRUE, # show H&E in grayscale
min.opacity = 255, # be default total cell density is shown by opacity, set min.opacity to max (255) to disable it.
bg = '#00000000', # set transparent background, so spots where neither of genes is expressed will be invisible
main='Kernel x^2'
)
# make it sharper (the only difference is zfun)
plotVisiumMultyColours(mob,exps,
cols = cols,
zfun = function(x)x^6, # kernel to transform gene expression. Higher powers will give more sharp figure (each spot will be dominated by single cell type)
mode = 'mean', # colors are averaged not overlayed (in this mode gene order makes no difference)
legend.ncol = 2, # show legend in two columns
he.grayscale = TRUE, # show H&E in grayscale
min.opacity = 255, # be default total cell density is shown by opacity, set min.opacity to max (255) to disable it.
bg = '#00000000', # set transparent background, so spots where neither of genes is expressed will be invisible
main='Kernel x^6'
)
Seven genes looks too many here to show them clearly all because some of them overlap.
IMPORTANT! By default each cell types is scaled individually so genes with high and low expression contributes equally to the plot. Use scale.per.colour = FALSE to disable it.
Usually pies are more confusing than mean colors, however in this case it allows to show overlapping Ptj2b/Penk and Lcat/Ly6g6e
par(mar=c(0,0,1,10),bty='n')
plotVisium(mob,pie.fracs=exps,
pie.cols = cols,
he.grayscale = TRUE, # show H&E in grayscale
)
legend(grconvertX(1,'npc','user'),grconvertY(1,'npc','user'),fill=cols,legend = paste0(m$gene,' (cl',m$cluster,')'),xpd=TRUE)